package com.geekbang;

import com.geekbang.supermarket.LittleSuperMarket;
import com.geekbang.supermarket.MerchandiseV2;

public class LittleSuperMarketAppMain {
    public static void main(String[] args) {
        LittleSuperMarket superMarket = new LittleSuperMarket("大卖场",
            "世纪大道1号", 500, 600, 100);

        // >> TODO *** 当父类的引用指向子类的实例（或者父类的实例），只能通过父类的引用，像父类一样操作子类的对象 ***
        // TODO m100 指向 ShellColorChangePhone, 对应describe是指向对象的方法
        MerchandiseV2 m0 = superMarket.getMerchandiseOf(0);
        m0.describe();
        System.out.println();
        MerchandiseV2 m100 = superMarket.getMerchandiseOf(100);
        m100.describe();
        System.out.println();
        MerchandiseV2 m10 = superMarket.getMerchandiseOf(10);
        m10.describe();

// TODO
//        父类引用可以指向子类对象，以及子类的子类的对象。
//        我们都知道，Java中引用类型是名实分离的，名就是引用，实就是实例。但以前我们用的是：Phone ph = new Phone()
//        而现在，我们可以用父类引用指向子类实例，就是说：
//        public class Phone extends MerchandiseV2{}
//        MerchandiseV2 m2 = new Phone();
//        我们前面说过，引用有类型，引用有实例，左手牵类型，右手牵实例。
//        我们使用m2.getBrand()这样的方式来调用方法，那么能调什么方法，看引用类型。m2能调用什么方法？
//        要看m2是什么类型，m2是MerchandiseV2类型，所以MerchandiseV2有什么方法，m2就能够调用什么方法。（当然也需要遵守访问修饰符的限制）
//        那实际调用哪个方法呢？要看引用指向的对象的类型。
//        比如说这里m2实际指向的是一个Phone()类型，那么m2.getBrand()就是要调用Phone类的getBrand()方法，如果Phone类没有getBrand()方法，
//        就会沿着继承链去找MerchandiseV2中有没有getBrand()方法。
//        也就是说，子类Phone覆写了父类MerchandiseV2的方法，那调用子类的，没有覆写调用的就是父类的。
// TODO
//        那么假如说，我不光有Phone1，还有Phone2，还有Phone3：
//        public class Phone1 extends MerchandiseV2{}
//        public class Phone2 extends MerchandiseV2{}
//        public class Phone3 extends MerchandiseV2{}
//        MerchandiseV2 m1 = new Phone1();
//        MerchandiseV2 m2 = new Phone2();
//        MerchandiseV2 m3 = new Phone3();
//        且Phone1，Phone2，Phone3都覆写了MerchandiseV2中的buy()方法：
//        那么m1.buy()调用的就是Phone1中的buy()方法，m2.buy()调用的就是Phone2中的buy()方法，m3.buy()调用的就是Phone3中的buy()方法。
//        引用决定了m可以调用buy()方法，而至于说这个buy()方法一次能买几个手机，是5个还是6个，
//        那就取决于引用指向的实例他是哪个Phone类，该类中是怎么实现的。这就是多态。
// TODO
//        父类引用可以指向子类实例是多态实现的前提条件。

    }
}
